/**
 * \file
 *           tlmRmtCfgSrvApp.cpp
 * \brief
 *           Implements tlmRmtCfgSrvApp class for Telematics
 *           this is the derived class from tlmServiceApp clas.
 *           It's the service class for remote configuration 
 *
 * \par Author (last changes):
 *          - Zeng Jie
 *          - BUIC, Continental Automotive Holdings Co., Ltd.
 * \par Project Leader:
 *          -
 * \par Responsible Developer:
 *          - Zeng Jie
 *          - BUIC, Continental Automotive Holdings Co., Ltd.
 * \par Responsible Architect:
 *          - Zhang Fa
 *          - BUIC, Continental Automotive Holdings Co., Ltd.
 *
 * \par Project:
 *      DPCA2
 *
 * \par SW-Component:
 *      Telematics
 *
 * \par SW-Package:
 *      Telematics
 *
 * \par SW-Module:
 *      Telematics Application
 *
 * \par SW-Architecture Specification:
 *      DPCA2_TELEMATICS_SW_DD_07a_ready.doc
 *
* \par SW-Design Specification:
 *      DPCA2_TLM-RMTCFG_SW_DD_01d_released.doc
 *
 * \par SW-Test Case Specification:
 *
 * \par CM-Info:
 *
 * \note
 *      This is a note.
 *
 * \bug
 *      - there are no known bugs
 *
 * \par Module-History:
 *
 * \verbatim
 * Date                Author					Reason
 * 10 Dec 2013        Zeng Jie              Initial Creation
 * The latest entry at the head of the history list.
 * \endverbatim
 *
 * \par Copyright Notice:
 * Copyright (C) 2012 Continental Automotive Holdings Co., Ltd.
 * Alle Rechte vorbehalten. All Rights Reserved.\n
 * The reproduction, transmission or use of this document or its contents is
 * not permitted without express written authority.\n
 * Offenders will be liable for damages. All rights, including rights created
 * by patent grant or registration of a utility model or design, are reserved.
 *
 */
#include "stdafx.h"
#include <wininet.h>
#include "tlmServiceFactory.h"
#include "tlmRmtCfgSrvApp.h"
#include "tlmRmtCfgDataInfo.h"
//## operation OnReceiveMsg(tlmServiceMsg)
#include "tlmServiceMsg.h"
#include "tlmRmtCfgSrvRpcSyncDesc.h"
#include "tlmRmtCfgSrvRpcAsyncDesc.h"
#include "teleLogTrace.h"
#include "ConnMgrApp.h"
#include "RmtCfgStateEvt.h"

#include "teleMainTimers.h"
#include "HiGraphTimer.h"

#include "HiGraphQueue.h"

#include "app_IEmbRegistryIDs.h"

extern HiGraphQueue gTeleQueue;
extern HiGraphTimer  gTeleTimer;

//## class tlmRmtCfgSrvApp
tlmRmtCfgSrvApp* tlmRmtCfgSrvApp::mpInstance;

/**
* \brief tlmRmtCfgSrvApp: this is constructor of tlmRmtCfgSrvApp class
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*/
tlmRmtCfgSrvApp::tlmRmtCfgSrvApp() : tlmServiceApp(), ActiveClass(), mAckStatus(TLM_ACK_STATUS_OK),  /*DG CPP2ISQP-ISQPcpp Rule 8.4.8-SCC_GRANT_00013*/
                                                                mParaAdmin(),mParaNavi(),mParaWeb(),mCurPendingMsg(NIL),mCurSetParaMsg(NIL),
                                                                mCurGetCfgMsg(NIL),mConnSessionId(0),mConnSessionFlag(0),
                                                                mSetSessionRetryCnt(0),mGetSessionRetryCnt(0), mLanguage(TLM_RMT_CFG_LANGUAGE_SIMPLE_CHINESE),
                                                                mServerURL(NIL),mServerName(NIL), mServerUrlPath(NIL){
    memset(mGenericVin, 0, sizeof(mGenericVin));   
    //set default VIN code as "0000000000"
    memcpy(mGenericVin, "0000000000", TLM_GENERIC_VIN_LEN);

    memset(SetMsgBuf, 0, sizeof(SetMsgBuf));
    memset(GetMsgBuf, 0, sizeof(GetMsgBuf));

    mServerName = new TCHAR[MAX_ADMIN_URL_STRING_LENGTH + 1];
    mServerUrlPath = new TCHAR[MAX_ADMIN_URL_STRING_LENGTH + 1];
}

/**
* \brief ~tlmRmtCfgSrvApp: this is destructor of tlmRmtCfgSrvApp class
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*/
tlmRmtCfgSrvApp::~tlmRmtCfgSrvApp() {
    if(mServerURL){
        delete [] mServerURL;
        mServerURL = NIL;
    }

    if(mServerName)
    {
        delete [] mServerName;
        mServerName =NIL;
    }

    if(mServerUrlPath)
    {
        delete [] mServerUrlPath;
        mServerUrlPath =NIL;
    }
    
}

/**
* \brief GetAckStatus: get the ack status which indicates save parameters status
*
* \note
*
* \param[in]
* - none
*
* \return
* - uint8_t : ack status
*
*/
uint8_t tlmRmtCfgSrvApp::GetAckStatus() {
    return mAckStatus;
}

/**
* \brief GetInstance: retrieve or create new instace of tlmRmtCfgSrvApp
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgSrvApp*: pointer to tlmRmtCfgSrvApp instance
*
*/
tlmRmtCfgSrvApp* tlmRmtCfgSrvApp::GetInstance() {
    if(mpInstance == NIL)
    {
        mpInstance = new tlmRmtCfgSrvApp;
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>\n", __FUNCTION__);
    }
    return mpInstance;
}

/**
* \brief destroyInstance: destroy action when the object is delete.
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*
*/
void tlmRmtCfgSrvApp::destroyInstance(void)
{
    //LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>\n", __FUNCTION__);
}

/**
* \brief initialize: this function initialization the service app.
*
* \note
*
* \param[in]
* - none
*
* \return
* - none
*
*/
void tlmRmtCfgSrvApp::initialize(void)
{
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>\n", __FUNCTION__);
    //OnInitialization();
}

/**
 *
 * \brief  This function perform the syncronize call of process handler class.
 *
 * \param p [in] Pointer of the data structure of RPC call
 *
 * \return - none
 */
void tlmRmtCfgSrvApp::__SyncCall(RPC_IOCTL_PTR p) {
    //#[ operation __SyncCall(RPC_IOCTL_PTR)
    tlmRmtCfgSrvRpcSyncDesc desc(p);
    desc.send(p->ac->mExecutionThread);
    //#]
}

/**
 * \brief  This function perform the Asyncronize call of process handler class.
 *
 * TestID: 
 *
 * \param p [in]  Pointer of the data structure of RPC call
 *
 * \return - none
 */
void tlmRmtCfgSrvApp::__AsyncCall(RPC_IOCTL_PTR p) {
    //#[ operation __AsyncCall(RPC_IOCTL_PTR)
    tlmRmtCfgSrvRpcAsyncDesc* pDesc = new tlmRmtCfgSrvRpcAsyncDesc(p);
    pDesc->send(p->ac->mExecutionThread);
    //#]
}




/**
* \brief GetParaAdmin : get the admin parameter object
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgParaAdmin* : pointer to admin parameter object
*
*/
tlmRmtCfgParaAdmin* tlmRmtCfgSrvApp::GetParaAdmin() {
    tlmRmtCfgParaAdmin * pParaAdmin = NIL;

    pParaAdmin = &mParaAdmin;
    return pParaAdmin;
}
/**
* \brief GetParaNavi : get the Navi parameter object
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgParaNavi* : pointer to Navi parameter object
*
*/
tlmRmtCfgParaNavi* tlmRmtCfgSrvApp::GetParaNavi() {
    tlmRmtCfgParaNavi * pParaNavi = NIL;

    pParaNavi = &mParaNavi;
    
    return pParaNavi;
}
/**
* \brief GetParaWeb : get the Web parameter object
*
* \note
*
* \param[in]
* - none
*
* \return
* - tlmRmtCfgParaWeb* : pointer to Web parameter object
*
*/
tlmRmtCfgParaWeb* tlmRmtCfgSrvApp::GetParaWeb() {
    tlmRmtCfgParaWeb * pParaWeb= NIL;

    pParaWeb = &mParaWeb;
    
    return pParaWeb;
}

/**
* \brief SaveParameters: Save parameters of remote configuration service
*
* \note
*
* \param[in]
* - none
*
* \return
* - uint8_t: save status
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_019]
*/
uint8_t tlmRmtCfgSrvApp::SaveParameters() {
    uint8_t status=TLM_ACK_STATUS_OK;
    status = mParaWeb.Save(); 
    if(status == TLM_ACK_STATUS_OK)
    {  
    	status = mParaNavi.Save(); 
    }  
    
    if(status == TLM_ACK_STATUS_OK)
    {  
    	status = mParaAdmin.Save(); 
    } 
    
    return status;
    //#]
}
/**
* \brief SendMsg: send the messag to server 
*
* \note
*
* \param[in]
* - msg: pointer to message object that include the message which shall be send.
*
* \return
* - none
*
*/
void tlmRmtCfgSrvApp::SendMsg(tlmServiceMsg* msg) { /*DG CPP2ISQP-ISQPcpp Rule 8.7.1-SCC_GRANT_0006*/
    //#]
    
    SendHttpMsg(msg->GetOutMsgPtr(),msg->GetTotalSize());

}

/**
* \brief tlmRmtCfgSrvApp_makeAsyncCall: this function is called to make async call function.
*
* \note
*
* \param[in]
* - funcID : the ID of the function that want to be called
* - pData  : paramteres passed to the function
* - size   : size of the paramters
*
* \return 
* - none
*
*/
void tlmRmtCfgSrvApp::tlmRmtCfgSrvApp_makeAsyncCall(DWORD funcId,DWORD* pData,DWORD size)
{
	LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TELE]:tlmRmtCfgSrvApp::makeAsyncCall %d\n", funcId);
	s_RPC_IOCTL mIoCTL;

	/* RPC IOCTL stucture */
    mIoCTL.ac = this;
	mIoCTL.dmFuncID = static_cast<uc8_t>(funcId);
	mIoCTL.lpInBuffer = reinterpret_cast<LPVOID>(pData);
	mIoCTL.nInBufferSize = static_cast<uc8_t>(size);
	mIoCTL.lpOutBuffer = 0;
	mIoCTL.nOutBufferSize = 0;

	this->AsyncCall(&mIoCTL);
}
/**
* \brief OnReceiveMsg: this function is called when received message
* 
* \note
*
* \param[in]
* - srvMsg: pointere to serviceMsg object which is the received message
*
* \return
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_005]
*/
void tlmRmtCfgSrvApp::OnReceiveMsg(tlmServiceMsg* srvMsg) {
    //#[ operation OnReceiveMsg(tlmServiceMsg)
    s_RPC_IOCTL lRpc;


	/* RPC IOCTL stucture */
	lRpc.ac = this;
	lRpc.dmFuncID = FUNCID_TLM_RMT_CFG_HANDLE_MSG;
	lRpc.lpInBuffer = reinterpret_cast<LPVOID *>(&srvMsg);
	lRpc.lpOutBuffer =  NIL;
	lRpc.nInBufferSize = static_cast<uc8_t>(sizeof(srvMsg));
	lRpc.nOutBufferSize = 0;


	this->AsyncCall(&lRpc);

    
    //__OnReceiveMsg(srvMsg);
    //#]
}

/**
* \brief __OnReceiveMsg:This function is the actual handler function to process the message 
*               it shall save the message if it's incoming traffic message
*               parse the data infomation section, and process it. 
* 
* \note
*
* \param[in]
* - srvMsg: pointere to serviceMsg object which is the received message
*
* \return
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_006]
*/
void tlmRmtCfgSrvApp::__OnReceiveMsg(tlmServiceMsg* srvMsg) {
	uint8_t msgType=0;
	bool_t retVal=true;

    if(srvMsg==NIL)
    {
	    LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, srvMsg is NIL\n", __FUNCTION__);
        retVal = false;
    }
    else
    {
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, srvMsg:0x%x\n", __FUNCTION__,srvMsg);
    
        //#[ operation __OnReceiveMsg(tlmServiceMsg)
        //srvMsg->SaveMsg();

        //here can process the message
        retVal = srvMsg->HandleData(); 
        if(retVal)
        {
            srvMsg->GetMsgType(msgType);
            switch(msgType)
            {
                case TLM_MSG_TYPE_RMT_CFG_PENDING:
                    {
                        CheckNewPendMsg(srvMsg);                        
                        break;    
                    }

                case TLM_MSG_TYPE_RMT_CFG_REQUEST:
                    {
                        CheckNewGetCfgMsg(srvMsg); 
                        break; 
                    }
                default:
                    {
                        LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, invalid msg type[%d]\n", __FUNCTION__,msgType);
                        break;
                    }
            }
        }
        else
        {
            LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, Handle data failed\n", __FUNCTION__);
        }

    }


    return;

    
    
    //#]
}


/**
* \brief CheckNewPendMsg: check the new received pending message
*           it first check  message unique id, if it's same as that of the current message it shall ignore the message, other wise, it post out event to start set parameters session.
*                   
*
* \note
*
* \param[in]
* - srvMsg : pointer to message instance.
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_007]
*/
void tlmRmtCfgSrvApp::CheckNewPendMsg(tlmServiceMsg* srvMsg) {
    //This function shall be called when receive pending message while the previous set config procss has not completed.
    uint16_t newMsgId = -1;
    uint16_t curMsgId = -1;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    if(srvMsg != NIL)
    {
        newMsgId = srvMsg->GetMsgUniqueId();
        if(mCurPendingMsg != NIL)
        {//this means the previous set session has not been finished.
            curMsgId = mCurPendingMsg->GetMsgUniqueId();
            if(newMsgId != curMsgId)
            {//received message is different with the current one 

                delete mCurPendingMsg;
                
                mCurPendingMsg = srvMsg;
                mSetSessionRetryCnt = 0;  //it's  new message, the stored message shall not be retried.
                
                gTeleQueue.postEvent(EVT_RMTCFG_RcvNewPendingMsg, 1);

                gTeleTimer.CancelTimer(RmtCfgSetCfgTimer);                
                gTeleTimer.SetTimer(RmtCfgSetCfgTimer, TLM_RMT_CFG_TIMEOUT, EVT_RMTCFG_SetCfgTimeOut, NIL);
            }
            else
            {
                LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> same ID[%d] message \n", __FUNCTION__, newMsgId);
            }
        }
        else
        {   
            mCurPendingMsg = srvMsg;
            gTeleQueue.postEvent(EVT_RMTCFG_RcvPendingMsg, 1);
            gTeleTimer.SetTimer(RmtCfgSetCfgTimer, TLM_RMT_CFG_TIMEOUT, EVT_RMTCFG_SetCfgTimeOut, NIL);
        }
    }
    else
    {
        LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<%s>, srvMsg is NIL\n", __FUNCTION__);

    }
    
    
}


/**
* \brief CheckNewGetCfgMsg: check the new received Get Config message
*           it first check  message unique id, if it's same as that of the current message it shall ignore the message, other wise, it post out event to start get parameters session.
*                   
*
* \note
*
* \param[in]
* - srvMsg : pointer to message instance.
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_008]
*/
void tlmRmtCfgSrvApp::CheckNewGetCfgMsg(tlmServiceMsg* srvMsg) {
    //This function shall be called when receive pending message while the previous set config procss has not completed.
    uint16_t newMsgId = -1;
    uint16_t curMsgId = -1;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    if(srvMsg != NIL)
    {
        newMsgId = srvMsg->GetMsgUniqueId();
        if(mCurGetCfgMsg != NIL)
        {//this means the previous set session has not been finished.
            curMsgId = mCurGetCfgMsg->GetMsgUniqueId();
            if(newMsgId != curMsgId)
            {//received message is different with the current one 

                delete mCurGetCfgMsg;
                mCurGetCfgMsg = srvMsg;
                mGetSessionRetryCnt = 0;  //it's  new message, the stored message shall not be retried.
                gTeleQueue.postEvent(EVT_RMTCFG_RcvNewGetCfgMsg, 1);

                gTeleTimer.CancelTimer(RmtCfgGetCfgTimer);                
                gTeleTimer.SetTimer(RmtCfgGetCfgTimer, TLM_RMT_CFG_TIMEOUT, EVT_RMTCFG_GetCfgTimeOut, NIL);
            }
            else
            {
                LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> same ID[%d] message \n", __FUNCTION__, newMsgId);
            }
        }
        else
        {   
            mCurGetCfgMsg = srvMsg;
            gTeleQueue.postEvent(EVT_RMTCFG_RcvGetCfgMsg, 1);
            gTeleTimer.SetTimer(RmtCfgGetCfgTimer, TLM_RMT_CFG_TIMEOUT, EVT_RMTCFG_GetCfgTimeOut, NIL);
        }
    }
    else
    {
        LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<%s>, srvMsg is NIL\n", __FUNCTION__);

    }

}

/**
* \brief onReceiveNewGetCfgMsg: this function shall be called when received new Get Cfg message
*
* \note
*
* \param[in]
* - srvMsg : service message instance pointer
*
* \return 
* - none
*
*/
void tlmRmtCfgSrvApp::onReceiveNewGetCfgMsg(tlmServiceMsg* srvMsg) {
    
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    if(mCurGetCfgMsg != NIL)
    {
        delete mCurGetCfgMsg;
        mCurGetCfgMsg = NIL;
    }
}



/**
* \brief RequestConnection: This function call connection manager interface to setup the connection, so that it can send HTTP message
*       if it has request connection ,and have not release the session id, it just need to check the connection status.
*       if Connection status is CS_CONNECTED, it post EVT_RMTCFG_ConnAvailable to send the message
*       this function use sessionMask to indicate if it's set or get config session
*
* \note
*
* \param[in]
* - sessionMask: mask to indicate if it's set or get config session
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_012]
*/
void tlmRmtCfgSrvApp::RequestConnection(uint8_t sessionMask) {
     E_CONN_STATUS status;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);
    
    ConnMgrApp* pConnMgrApp = const_cast<ConnMgrApp*>(&(ConnMgrApp::getInstance()));
    if(pConnMgrApp)
    {
        mConnSessionFlag |= sessionMask;
    
        if(mConnSessionId == 0)
        {//has not request network, need to set up it.
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> request new connection\n", __FUNCTION__);
            pConnMgrApp->onReqConnection(tlmSrcTlm,&mConnSessionId,&status);
        }
        else
        {//the request has been done, no need to set up it again
            status = pConnMgrApp->onGetConnStatus();
        }

        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> status[%d]\n", __FUNCTION__, status);

        if(status == CS_CONNECTED)
        {
            gTeleQueue.postEvent(EVT_RMTCFG_ConnAvailable, NIL);
        }        
        
        
    }
    else
    {
	    LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, ConnMgrApp instance is NIL\n", __FUNCTION__);
    }
}




/**
* \brief OpenHttpSession: this function use wininet API to open http session
*
* \note
*
* \param[in]
* -hSession : handle returned by the InternetOpen
* -hConnect : handle returned by InternetConnect
* -hRequest : handle returned by HttpOpenRequest
*
* \return 
* bool_t : true - open HTTP session succesfully
*          false - failed to open HTTP session
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_026]
*/
bool_t tlmRmtCfgSrvApp::OpenHttpSession(HINTERNET& hSession, HINTERNET& hConnect,HINTERNET& hRequest) const{/*DG CPP2ISQP-ISQPcpp Rule 8.7.1-SCC_GRANT_0006*/

    bool_t retVal=true; 
    
    
    hSession = InternetOpen( TEXT("RemoteConfigMsg"), INTERNET_OPEN_TYPE_PRECONFIG,
                                                    NIL, NIL, 0);
    if(!hSession)
    {
        LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed to open session>\r\n",__FUNCTION__);
        retVal=false;    
    }
   
    

    if(retVal)
    {
        if(!mServerURL)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::default IP address>\r\n",__FUNCTION__);
            hConnect = InternetConnect(hSession,  TEXT("192.168.1.25"), INTERNET_DEFAULT_HTTP_PORT,
                                                                    NIL, NIL, INTERNET_SERVICE_HTTP,NIL, NIL);
        }
        else
        {
            uint8_t tmpBuf[MAX_ADMIN_URL_STRING_LENGTH+1];
            memset(tmpBuf, 0, sizeof(tmpBuf));
            WideCharToMultiByte(CP_ACP , 0 , mUrlComp.lpszHostName, -1, reinterpret_cast<LPSTR>(tmpBuf), MAX_ADMIN_URL_STRING_LENGTH, NIL, NIL);
            
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<host name:%s, port:%d>\r\n",tmpBuf,mUrlComp.nPort);
            hConnect = InternetConnect(hSession, mUrlComp.lpszHostName, mUrlComp.nPort,
                                                                    NIL, NIL, INTERNET_SERVICE_HTTP,NIL, NIL);
        }
        
        if (!hConnect)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed to connect>\r\n",__FUNCTION__);
            retVal=false; 
        }
        
    }

    if(retVal)
    {
        if(!mServerURL)
        {
            hRequest = HttpOpenRequest(hConnect, TEXT("POST"), TEXT("TelematicsHandler.ashx"), 
                            NIL, NIL, NIL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
        }
        else
        {
            uint8_t tmpBuf[MAX_ADMIN_URL_STRING_LENGTH+1];
            memset(tmpBuf, 0, sizeof(tmpBuf));
            WideCharToMultiByte(CP_ACP , 0 , mUrlComp.lpszUrlPath, -1, reinterpret_cast<LPSTR>(tmpBuf), MAX_ADMIN_URL_STRING_LENGTH, NIL, NIL);
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<url path:%s>\r\n",tmpBuf);
            hRequest = HttpOpenRequest(hConnect, TEXT("POST"), mUrlComp.lpszUrlPath, 
                            NIL, NIL, NIL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
        }
        
        if (!hRequest)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed to open request handle>\r\n",__FUNCTION__);
            retVal=false;
        }

    }

    return retVal;

}

/**
* \brief CloseHttpSession: this function use wininet API to close http session
*
* \note
*
* \param[in]
* -hSession : handle returned by the InternetOpen
* -hConnect : handle returned by InternetConnect
* -hRequest : handle returned by HttpOpenRequest
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_027]
*/
void tlmRmtCfgSrvApp::CloseHttpSession(HINTERNET& hSession, HINTERNET& hConnect,HINTERNET& hRequest){
    if(hRequest)
    {
        if(InternetCloseHandle(hRequest))
        {
            hRequest=NIL;
            //LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>close hRequest\r\n",__FUNCTION__);
        }
        else
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>Failed close hRequest, [%d]\r\n",__FUNCTION__, GetLastError());
        }
    }

    if(hConnect)
    {
        if(InternetCloseHandle(hConnect))
        {
            hConnect=NIL;
            //LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>close hConnect\r\n",__FUNCTION__);
        }
        else
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>Failed close hConnect, [%d]\r\n",__FUNCTION__, GetLastError());
        }
    }
    if(hSession)
    {
        if(InternetCloseHandle(hSession))
        {
            hSession=NIL;
            //LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>close hSession\r\n",__FUNCTION__);
        }
        else
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>Failed close hSession, [%d]\r\n",__FUNCTION__, GetLastError());
        }
    }
}

/**
* \brief GetHttpResponseData : use wininet API to get the HTTP response data
*                 it first query content length, the query if data is available, if yes, call InternetReadFile to get the response data
*
* \note
*
* \param[in]
* -hRequest : handle returned by HttpOpenRequest
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_029]
*/
bool_t tlmRmtCfgSrvApp::GetHttpResponseData(HINTERNET hRequest){
    DWORD dwSize = 10;
    char * lpOutBuffer = new char[dwSize];
    bool_t retVal=true;
    uint32_t contentLen = 0;

    //StringCchPrintfA((LPSTR)lpOutBuffer,dwSize,"Content-Length");


    if(!HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH , (LPVOID)lpOutBuffer,&dwSize,NIL))    /*DG CPP2ISQP-ISQPcpp Rule 5.5.9-MMP_ExtGen_0001*/
    {
        DWORD dw = GetLastError();
        LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed queryinfo,  err[%d][%d]>\r\n",__FUNCTION__, dw,dwSize);
        retVal = false;
    }
    else
    {
        //int len = atol(static_cast<const char *>(lpOutBuffer));
        #ifdef UNICODE
        contentLen = _wtol(reinterpret_cast<const wchar_t *>(lpOutBuffer));
        #else
        contentLen = atol(lpOutBuffer);
        #endif
        
        LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::content length[%d]>\r\n",__FUNCTION__, contentLen);

        if(contentLen == 0)
        {//This indicates its an HTTP OK response
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::httprsp:OK>\r\n",__FUNCTION__);
            gTeleQueue.postEvent(EVT_RMTCFG_RcvHttpOKResp, NIL);
        }
    }

    if(retVal && (contentLen != 0))
    {
        DWORD  dwBytesRead=0;
        DWORD  dwSize=0;
        uint8_t * pcBuffer=NIL;

        uint8_t *msgPayload = new uint8_t[contentLen];

        if(msgPayload != NIL)
        {
            uint8_t * pTemp = msgPayload;
            
            do
            {	
                dwBytesRead=0;
                if (!InternetQueryDataAvailable(hRequest,&dwSize,0,0))
                {
                    LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed to query data>\r\n",__FUNCTION__);
                    retVal=false;
                    break;
                }

                //LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::dwSize[%d]>\r\n",__FUNCTION__, dwSize);

                pcBuffer = new uint8_t[dwSize];
                
                
                if(InternetReadFile(hRequest, (LPVOID)pcBuffer, dwSize, &dwBytesRead))   /*DG CPP2ISQP-ISQPcpp Rule 5.5.9-MMP_ExtGen_0001*/
                {
                    //LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::read data bytes[%d]>\r\n",__FUNCTION__, dwBytesRead);   	

                    memcpy(pTemp, pcBuffer, dwBytesRead);

                    pTemp += dwBytesRead;
                }
                else
                {
                    LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed to read file>\r\n",__FUNCTION__);
                    
                    retVal = false;
                    
                }

                delete [] pcBuffer;            
            }while((dwBytesRead>0) && (retVal!=false));

            OnReceiveHttpMsg(msgPayload, contentLen);

            delete [] msgPayload;
        }        
    }

    delete [] lpOutBuffer;

    return retVal;

   
}

/**
* \brief GetHttpResponseStatus : use wininet API to get the HTTP response status
*          if the status is not OK, it shall return false to indicate fail
*
* \note
*
* \param[in]
* -hRequest : handle returned by HttpOpenRequest
*
* \return 
* bool_t : true - get response status HTTP 200 OK
*          false - get other status which is not HTTP 200 OK
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_028]
*/
bool_t tlmRmtCfgSrvApp::GetHttpResponseStatus(HINTERNET hRequest){
    bool_t retVal=true;
    DWORD dwSize = 128;
    char * lpOutBuffer = new char[dwSize];
    uint32_t httpStatus=0;

    //StringCchPrintfA((LPSTR)lpOutBuffer,dwSize,"Content-Length");

    if(!HttpQueryInfo(hRequest,HTTP_QUERY_STATUS_CODE  , (LPVOID)lpOutBuffer,&dwSize,NIL))     /*DG CPP2ISQP-ISQPcpp Rule 5.5.9-MMP_ExtGen_0001*/
    {
        DWORD dw = GetLastError();
        LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed query status,  err[%d][%d]>\r\n",__FUNCTION__, dw,dwSize);
        retVal = false;
    }
    else
    {
        //int len = atol(static_cast<const char *>(lpOutBuffer));
        #ifdef UNICODE
        httpStatus = _wtol(reinterpret_cast<const wchar_t *>(lpOutBuffer));
        #else
        httpStatus = atol(lpOutBuffer);
        #endif

        if(httpStatus != HTTP_STATUS_OK )
        {
            retVal = false;
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::status[%d]>\r\n",__FUNCTION__, httpStatus);
        }           
        
    }

    delete [] lpOutBuffer;

    return retVal;
}

/**
* \brief SendHttpMsg: call this function to send the HTTP message
*
* \note
*
* \param[in]
* - msgPayload : pointer to the message buffer
* - length : length of the message shall be send
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_016]
*/
void tlmRmtCfgSrvApp::SendHttpMsg(uint8_t* msgPayload, uint32_t length) {
    HINTERNET hRequest = NIL;
    HINTERNET hConnect=NIL;    
    HINTERNET hSession = NIL;
    bool_t retVal=true;

    retVal = OpenHttpSession(hSession, hConnect, hRequest);

    if(retVal)
    {//all http Session has been opened successfully. 

        if(!HttpSendRequest(hRequest, NIL, -1, msgPayload, length))
        {                            
            DWORD dw = GetLastError();
            LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s::Failed to send request,  err[%d]>\r\n",__FUNCTION__, dw);
            retVal=false;
        }
    }

    if(retVal)
    {
        retVal = GetHttpResponseStatus(hRequest);
    }

    if(retVal)
    {
        retVal = GetHttpResponseData(hRequest);
    }

    CloseHttpSession(hSession, hConnect, hRequest);

    
}

/**
* \brief OnReceiveHttpMsg: when receive HTTP message, shall call this function to handle it. The function shall create message instance using received message buffer
*
* \note
*
* \param[in]
* - msgPayload : pointer to message payload
* - length : length of the message received
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_017]
*/
void tlmRmtCfgSrvApp::OnReceiveHttpMsg(uint8_t* msgPayload, uint32_t length){
    bool_t retVal=true;
    tlmServiceMsg * srvMsg=NIL;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>\n", __FUNCTION__);
    
    if( msgPayload == NIL || length == 0 ){  
    	LOG_PRINT( DPCA_TELE_MAIN_ERROR, "[TLM_RMTCFG] invalid payload or length %s", __FUNCTION__);
        retVal = false;
    }
    if(retVal)
    {

    //create a new srvMsg instance, it shall pass to the service, and delete by the service
        srvMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(msgPayload, length);
        if(srvMsg != NIL)
        {
                
            __OnReceiveHttpMsg(srvMsg);
        }
    }
}

/**
* \brief __OnReceiveHttpMsg: Actual function to handle received HTTP message which is a message instance
*                          It shall check message type and service type, only "set parameters" message is correct.
*
* \note
*
* \param[in]
* - srvMsg : pointer to service message instance
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_018]
*/
void tlmRmtCfgSrvApp::__OnReceiveHttpMsg(tlmServiceMsg* srvMsg) {
    uint8_t srvType=0;
    uint8_t msgType=0;
    bool_t retVal=true;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>\n", __FUNCTION__);

    if(srvMsg != NIL)
    {
        srvMsg->ParseInit();

        srvMsg->GetSrvType(srvType);    

        srvMsg->GetMsgType(msgType);

        //can only receive set para messag via HTTP.
        if((srvType == TLM_SRV_TYPE_REMOTE_CONFIG) && (msgType == TLM_MSG_TYPE_RMT_CFG_SET_PARA) )
        {
            retVal = srvMsg->HandleData();  

            //as only set para message shall be received via HTTP
            //This function shall only process set para message, so just send this event.
            //The last http 200 ok response message is not processed at here.
            mCurSetParaMsg = srvMsg;
            gTeleQueue.postEvent(EVT_RMTCFG_RcvSetCfgMsg, 1 );
        } 
        else
        {
            retVal = false;
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s> invalid srvType[%d] or msgType [%d]\n", __FUNCTION__,srvType, msgType);
        }
    }
    else
    {
        retVal = false;
    }

    

    return;

    
    
    //#]
}



/**
* \brief HandleGetCfgMsg: This function is used to handle Get Config message
*                 it saves message into persistency. check which parameters is requested to send to server.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_010]
*/
void tlmRmtCfgSrvApp::HandleGetCfgMsg(void) {

//#[ operation __OnReceiveReqParaMsg(tlmServiceMsg)
    //Received an pending message(mstType:0x28), need send parameters message to offboard server.
    tlmRmtCfgParaWeb *pParaWeb = NIL;     
    tlmRmtCfgParaNavi *pParaNavi = NIL;
    tlmRmtCfgParaAdmin *pParaAdmin = NIL; 
    tlmRmtCfgDataInfo *pDataInfo = NIL;
    DWORD status = 0;

    tlmServiceMsg * srvMsg = mCurGetCfgMsg;
    
    if(NIL != srvMsg)
    {
        uint8_t msgType=0;

        status = ssw_ergUserWriteData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_GET,srvMsg->getMInMsgPtr(), SIZE_ERG_DPCA_TLM_REMOTECFG_GET);

        if(status != ER_ERG_SUCCESS)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]: Save get Cfg message failed Error=%lx \n", status);
        }
        
            
        srvMsg->GetMsgType(msgType);
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, receive reqPara message[%d]\n", __FUNCTION__,msgType);
        pDataInfo = reinterpret_cast<tlmRmtCfgDataInfo*>(srvMsg->GetDataInfo());

        if(pDataInfo != NIL)
        {
            //check if the parameters is requested to send
            pParaWeb = pDataInfo->GetParaWeb();
            if(pParaWeb!=NIL)
            {
                mParaWeb.SetRequested(pParaWeb->IsRequested());  
                pParaWeb->ClearRequested();
            } 

            //check if the parameters is requested to send
            pParaNavi = pDataInfo->GetParaNavi();
            if(pParaNavi!=NIL)
            {
                
                mParaNavi.SetRequested(pParaNavi->IsRequested());      
                
            } 

            //check if the parameters is requested to send
            pParaAdmin = pDataInfo->GetParaAdmin();
            if(pParaAdmin!=NIL)
            {   
                //set the current para flag
                mParaAdmin.SetRequested(pParaAdmin->IsRequested()); 

                //clear the component in message.
                pParaAdmin->ClearRequested();
            } 
        }

        //gTeleQueue.postEvent(EVT_RMTCFG_ReqConnection, NIL);
        RequestConnection(TLM_RMT_CFG_GET_SESSION_MASK);

        

    }
    else
    {
	    LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, srvMsg is NIL\n", __FUNCTION__);
    }



    
}

/**
* \brief HandlePendingMsg: This function is used to handle Pending message
*                 it saves message into persistency, then requeste connection
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_009]
*/
void tlmRmtCfgSrvApp::HandlePendingMsg(void) {
    DWORD status = 0;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    tlmServiceMsg * srvMsg = mCurPendingMsg;
    if(srvMsg != NIL)
    {//
        status = ssw_ergUserWriteData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_SET,srvMsg->getMInMsgPtr(), SIZE_ERG_DPCA_TLM_REMOTECFG_SET);

        if(status != ER_ERG_SUCCESS)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]: Save pending message failed Error=%lx \n", status);
        }
    }

    
    RequestConnection(TLM_RMT_CFG_SET_SESSION_MASK);
        
}

/**
* \brief HandleSetConfigMsg: This function is used to handle Set Config message
*                 it gets paresed data information ,save updated parameters into persistency.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_011]
*/
void tlmRmtCfgSrvApp::HandleSetConfigMsg(void) {

    tlmRmtCfgParaWeb *pParaWeb = NIL;     
    tlmRmtCfgParaNavi *pParaNavi = NIL;
    tlmRmtCfgParaAdmin *pParaAdmin = NIL;
    tlmRmtCfgDataInfo * pDataInfo = NIL;
    tlmServiceMsg* srvMsg=NIL;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>\n", __FUNCTION__);

    srvMsg = mCurSetParaMsg;
    mCurSetParaMsg = NIL;

    if(NIL == srvMsg)
    {
	    LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<tlmRmtCfgSrvApp::%s>, srvMsg is NIL\n", __FUNCTION__);
    }
    else
    {
        
        pDataInfo = reinterpret_cast<tlmRmtCfgDataInfo*>(srvMsg->GetDataInfo());
        if(pDataInfo != NIL)
        {
            //update the web parameters
            pParaWeb = pDataInfo->GetParaWeb();
            if(pParaWeb!=NIL)
            {
                mParaWeb.Update(pParaWeb);
            } 

            //update the navi parameters  
            pParaNavi = pDataInfo->GetParaNavi();
            if(pParaNavi!=NIL)
            {
                mParaNavi.Update(pParaNavi);
            }  

            //update the Admin parameters
            pParaAdmin = pDataInfo->GetParaAdmin();
            if(pParaAdmin!=NIL)
            {
                mParaAdmin.Update(pParaAdmin);
            }
            mAckStatus=SaveParameters();  
        }
        else
        {
            mAckStatus=TLM_ACK_STATUS_KO;  
        }
        

        //After update message, we shall send Ack message to offboard server.  

        //gTeleQueue.postEvent(EVT_RMTCFG_ReqConnection, NIL);
        RequestConnection(TLM_RMT_CFG_SET_SESSION_MASK);
        

        

    }
}

/**
* \brief SendParaMsg: This function is used to send parameter message
*                 In HandleGetCfgMsg, it request connection, if the connection becomes available, this function shall be caled.
*                 It first initialize the message filed, fill all filed into message buffer, then send it out by HTTP protocol.
*                 It also start a 30s timer, if it does not received response, after time out, this function shall be called again.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_015]
*/
void tlmRmtCfgSrvApp::SendParaMsg(void){
 
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    tlmServiceMsg* pSendParaMsg=NIL;
    pSendParaMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(TLM_SRV_TYPE_REMOTE_CONFIG,TLM_MSG_TYPE_RMT_CFG_SEND_PARA);

    if(pSendParaMsg!=NIL)
    {    
        pSendParaMsg->SetItsService(reinterpret_cast<tlmServiceApp*>(GetInstance()));
        pSendParaMsg->Init();

        //the msg unique id shall be adjusted.
        uint16_t msgId = GetGetCfgMsgId();
        pSendParaMsg->SetHdrUniqueId(msgId);
        
        pSendParaMsg->Fill();

        gTeleTimer.SetTimer(RmtCfgGetCfgSendMsgTimer, TLM_RMT_CFG_SEND_MSG_TIMEOUT, EVT_RMTCFG_GetCfgSendMsgTimeOut, NIL);
        
        SendMsg(pSendParaMsg);

        delete pSendParaMsg;

    }         
    else
    {
        LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]:<%s>, create sendPara message failed\n", __FUNCTION__);
    }

    //After send the message, shall clear the requested flag.
    mParaWeb.ClearRequested();
    mParaNavi.ClearRequested();
    mParaAdmin.ClearRequested();

}

/**
* \brief SendConMsg: This function is used to send connection message
*                 In HandlePendingMsg, it request connection, if the connection becomes available, this function shall be caled.
*                 It first initialize the message filed, fill all filed into message buffer, then send it out by HTTP protocol.
*                 It also start a 30s timer, if it does not received response, after time out, this function shall be called again.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_013]
*/
void tlmRmtCfgSrvApp::SendConMsg(void){

    tlmServiceMsg* pConMsg=NIL;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);
    
    pConMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(TLM_SRV_TYPE_REMOTE_CONFIG,TLM_MSG_TYPE_RMT_CFG_CONNECT);
    
    if(pConMsg!=NIL)
    {
        pConMsg->SetItsService(reinterpret_cast<tlmServiceApp*>(GetInstance()));
        pConMsg->Init();

        //the msg unique id shall be adjusted.
        uint16_t msgId = GetSetCfgMsgId();
        pConMsg->SetHdrUniqueId(msgId);
        pConMsg->Fill();

        gTeleTimer.SetTimer(RmtCfgSetCfgSendMsgTimer, TLM_RMT_CFG_SEND_MSG_TIMEOUT, EVT_RMTCFG_SetCfgSendMsgTimeOut, NIL);

        SendMsg(pConMsg);

        delete pConMsg;

    }
}

/**
* \brief SendAckMsg: This function is used to send acknowledge message
*                 In HandleSetCfgMsg, it request connection, if the connection becomes available, this function shall be caled.
*                 It first initialize the message filed, fill all filed into message buffer, then send it out by HTTP protocol.
*                 It also start a 30s timer, if it does not received response, after time out, this function shall be called again.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_014]
*/
void tlmRmtCfgSrvApp::SendAckMsg(void){
   
    tlmServiceMsg* pAckMsg=NIL;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);
    
    pAckMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(TLM_SRV_TYPE_REMOTE_CONFIG,TLM_MSG_TYPE_RMT_CFG_ACK);

    if(pAckMsg!=NIL)
    {    
        pAckMsg->SetItsService(reinterpret_cast<tlmServiceApp*>(GetInstance()));
        pAckMsg->Init();
        //the msg unique id shall be adjusted.
        uint16_t msgId = GetSetCfgMsgId();
        pAckMsg->SetHdrUniqueId(msgId);
        pAckMsg->Fill();

        gTeleTimer.SetTimer(RmtCfgSetCfgSendMsgTimer, TLM_RMT_CFG_SEND_MSG_TIMEOUT, EVT_RMTCFG_SetCfgSendMsgTimeOut, NIL);
        SendMsg(pAckMsg);

        delete pAckMsg;
    }
}

/**
* \brief OnGetCfgTimeOut: If Get configuration session deos not finished in 120s, this function shall be called.
*                       It deletes current get config message, which means no get session is running.
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_022]
*/
void tlmRmtCfgSrvApp::OnGetCfgTimeOut(void){
 
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    if(mCurGetCfgMsg != NIL)
    {
        delete mCurGetCfgMsg;
        mCurGetCfgMsg = NIL;
    }

    //gTeleTimer.CancelTimer(RmtCfgGetCfgTimer);

}

/**
* \brief OnSetCfgTimeOut: If Set configuration session deos not finished in 120s, this function shall be called.
*                       It deletes current pending message, which means no set session is running.
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_023]
*/
void tlmRmtCfgSrvApp::OnSetCfgTimeOut(void){
 
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    if(mCurPendingMsg != NIL)
    {
        delete mCurPendingMsg;
        mCurPendingMsg = NIL;
    }
    //gTeleTimer.CancelTimer(RmtCfgSetCfgTimer);

}

void tlmRmtCfgSrvApp::CrackUrl(void)
{


    LOG_PRINT(DPCA_TELE_MAIN_INFO, "[TLM_MSGSRV]:<%s>\r\n",__FUNCTION__);
    
    mUrlComp.dwStructSize = sizeof(mUrlComp);
    mUrlComp.lpszScheme = NIL;
    mUrlComp.lpszHostName =  mServerName;
    mUrlComp.lpszUserName = NIL;
    mUrlComp.lpszPassword = NIL;
    mUrlComp.lpszUrlPath = mServerUrlPath;
    mUrlComp.lpszExtraInfo = NIL;

    mUrlComp.dwSchemeLength = 0;
    mUrlComp.dwHostNameLength = 1000;
    mUrlComp.dwUserNameLength = 0;
    mUrlComp.dwPasswordLength = 0;
    mUrlComp.dwUrlPathLength = 1000;
    mUrlComp.dwExtraInfoLength = 0;

     InternetCrackUrl(mServerURL, 0, 0, &mUrlComp);
        


}


/**
* \brief InitParaAdmin: This function initializes admin parameters. 
*                  It reads admin parameters from persistency, and initializes mParaAdmin memeber of the service
*                  It also initializes mServerURL by using url of the admin paramter.
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_002]
*/
void tlmRmtCfgSrvApp::InitParaAdmin(void) {
    //PSA defined ADMIN URL: http://58.254.177.52:8080/vca/vhlReceiveGateway

    DWORD status = 0;
    
    S_TLM_REMOTE_CFG_ADMIN_DATA sAdminData;  
    
    uint32_t u32RegSize = 0;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>2\n", __FUNCTION__);

    do{

        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

        memset(&sAdminData, 0, sizeof(sAdminData));
        status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_ADMIN,
                                                        reinterpret_cast<uint8_t*> (&sAdminData), sizeof(sAdminData), &u32RegSize);

        if(status != ER_ERG_SUCCESS)
        {
            LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[TLM_MSGSRV]: %s Persistency Reading failed.\n",__FUNCTION__);
            break;
        }
        
        mParaAdmin.InitUrl(sAdminData.adminURL);
        mParaAdmin.InitRecFilter(sAdminData.recFilter);
        mParaAdmin.InitSrvVin(sAdminData.serviceVIN); 


        if( strlen( reinterpret_cast<char*>(sAdminData.adminURL) ) == 0 )
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]: %s Invalid AdminUrl\n",__FUNCTION__);            
            break;
        }


        
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]: %s got url from persistency:%s.\n",__FUNCTION__, sAdminData.adminURL);            

        int iWide_Buffer_Size = MultiByteToWideChar(CP_ACP , 0 , reinterpret_cast<char*>(sAdminData.adminURL) , -1 , NIL , 0);
        if( iWide_Buffer_Size <= 0){
            LOG_PRINT(DPCA_TELE_ADMIN_ERROR,"[TLM_MSGSRV]: %s Invalid URL length.\n",__FUNCTION__);        
            break;
        }

        mServerURL = new TCHAR[iWide_Buffer_Size + 1];
        if( !mServerURL )
        {//allocation failed.
            LOG_PRINT(DPCA_TELE_ADMIN_ERROR,"[TLM_MSGSRV]: %s No enough memory.\n",__FUNCTION__);
            break;            
        }

        memset(mServerURL, 0, iWide_Buffer_Size + 1);
        
        if( MultiByteToWideChar(CP_ACP , 0 , 
                reinterpret_cast<char*>(sAdminData.adminURL), 
                -1 , mServerURL , iWide_Buffer_Size) == 0){
            LOG_PRINT(DPCA_TELE_ADMIN_ERROR,"[TLM_MSGSRV]: %s MultiByteToWideChar Failed.\n",__FUNCTION__);
            break;
        }     

        CrackUrl();
        
       
    }
    while(false);

    
}

/**
* \brief InitParaWeb: This function initializes web parameters. 
*                  It reads web parameters from persistency, and initializes mParaWeb memeber of the service
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_003]
*/

void tlmRmtCfgSrvApp::InitParaWeb(void) {
    DWORD status = 0;
    
    S_TLM_REMOTE_CFG_WEB_DATA sWebData;   
    
    uint32_t u32RegSize = 0;
    memset(&sWebData, 0, sizeof(sWebData));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_NAVI_REMOTECFG_WEB,
                                                    reinterpret_cast<uint8_t*> (&sWebData), sizeof(sWebData), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        mParaWeb.InitFreeSurfStatus(reinterpret_cast<uint8_t*>(&sWebData.freeSurf));
        mParaWeb.InitRmtHmiStatus(reinterpret_cast<uint8_t*>(&sWebData.remoteHMIStatus));
        mParaWeb.InitSpeedThreshold(reinterpret_cast<uint8_t*>(&sWebData.speedThreshold));
        mParaWeb.InitWebPortalStatus(reinterpret_cast<uint8_t*>(&sWebData.webPortal));
        mParaWeb.InitWebPortalSubStatus(reinterpret_cast<uint8_t*>(&sWebData.webPortalSubStatus));        
        
    }
}

/**
* \brief InitParaNavi: This function initializes NAVI parameters. 
*                  It reads NAVI parameters from persistency, and initializes navi parameter memebers of the service
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_004]
*/
void tlmRmtCfgSrvApp::InitParaNavi(void) {
    DWORD status = 0;
    
    S_TLM_REMOTE_CFG_TRAFFIC sTrafficData;
    S_TLM_REMOTE_CFG_LOCAL_SEARCH sLocalSrchData;
    S_TLM_REMOTE_CFG_WEATHER sWeatherData;
    S_TLM_REMOTE_CFG_PARKING sParkingData;
    S_TLM_REMOTE_CFG_GAS_STATION sGasStationData;   
    
    uint32_t u32RegSize = 0;

    memset(&sLocalSrchData, 0, sizeof(sLocalSrchData));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_NAVI_REMOTECFG_LOCALSEARCH,
                                                    reinterpret_cast<uint8_t*> (&sLocalSrchData), sizeof(sLocalSrchData), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        mParaNavi.InitLocalSrchUrl(sLocalSrchData.localSearchURL);        
        mParaNavi.InitLocalSrchStatus(reinterpret_cast<uint8_t*>(&sLocalSrchData.localSearchStatus)); 
        
    }

    memset(&sParkingData, 0, sizeof(sParkingData));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_NAVI_REMOTECFG_PARKING,
                                                    reinterpret_cast<uint8_t*> (&sParkingData), sizeof(sParkingData), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        mParaNavi.InitParkingUrl(sParkingData.parkingURL);        
        mParaNavi.InitParkingStatus(reinterpret_cast<uint8_t*>(&sParkingData.parkingStatus));         
    }

    memset(&sWeatherData, 0, sizeof(sWeatherData));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_NAVI_REMOTECFG_WEATHER,
                                                    reinterpret_cast<uint8_t*> (&sWeatherData), sizeof(sWeatherData), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        mParaNavi.InitWeatherUrl(sWeatherData.weatherURL);        
        mParaNavi.InitWeatherStatus(reinterpret_cast<uint8_t*>(&sWeatherData.weatherStatus));         
    }

    memset(&sGasStationData, 0, sizeof(sGasStationData));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_NAVI_REMOTECFG_GASSTATION,
                                                    reinterpret_cast<uint8_t*> (&sGasStationData), sizeof(sGasStationData), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        mParaNavi.InitGasStationUrl(sGasStationData.stationURL);        
        mParaNavi.InitGasStationStatus(reinterpret_cast<uint8_t*>(&sGasStationData.stationStatus));         
    }

    memset(&sTrafficData, 0, sizeof(sTrafficData));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_NAVI_REMOTECFG_TRAFFIC,
                                                    reinterpret_cast<uint8_t*> (&sTrafficData), sizeof(sTrafficData), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        mParaNavi.InitTrafficUrl(sTrafficData.trafficURL);        
        mParaNavi.InitTrafficPeriod(reinterpret_cast<uint8_t*>(&sTrafficData.trafficPeriod));  
        mParaNavi.InitTrafficFmStatus(reinterpret_cast<uint8_t*>(&sTrafficData.trafficInfoOverFM));      
        mParaNavi.InitTrafficInfoStatus(reinterpret_cast<uint8_t*>(&sTrafficData.trafficInfoStatus));      
        
    }
}

/**
* \brief UpdateGenericVin: This function update geneic vin code of the service. 
*
* \note
*
* \param[in]
* - data : pointer to generic vin code buffer
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_040]
*/
void tlmRmtCfgSrvApp::UpdateGenericVin(const uint8_t * data){
    uint8_t tempVin[10];
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    if(data != NIL)
    {
        if(data[0]==0)
        {//this vin code is default value, it does not get from can, we should use "0000000000"
            memcpy(mGenericVin, "0000000000", TLM_GENERIC_VIN_LEN);
        }
        else
        {
            tempVin[0] = data[12];
            tempVin[1] = data[13];
            tempVin[1] = data[13];
            memcpy(&tempVin[2], &data[1], 8);
                
            memcpy(mGenericVin, tempVin, TLM_GENERIC_VIN_LEN);
        }        
        
    }

}

/**
* \brief UpdateImxSysInfo: This function update Imx system information of the service. 
*
* \note
*
* \param[in]
* - data : pointer to buffer which contains IMX system information.
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_041]
*/
void tlmRmtCfgSrvApp::UpdateImxSysInfo(const uint8_t * data){
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);
    
    if(data != NIL)
    {
        memset(&mSysInfoImx, 0, sizeof(mSysInfoImx));
        memcpy(&mSysInfoImx, data, sizeof(mSysInfoImx));
    }
}
/**
* \brief UpdateLanguage: This function update language of the service. 
*
* \note
*
* \param[in]
* - language: language value
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_042]
*/
void tlmRmtCfgSrvApp::UpdateLanguage(uint8_t  language){

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> %d\n", __FUNCTION__, language);

    if(CONFIG_LANG_CHINESE == language)
    {
        mLanguage = TLM_RMT_CFG_LANGUAGE_SIMPLE_CHINESE;    
    }
    else if(CONFIG_LANG_ENGLISH == language)
    {
        mLanguage = TLM_RMT_CFG_LANGUAGE_ENGLISH;
    }
           
}

/**
* \brief InitVin: This function use default vin code to initialize mGenericVin. 
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
*/
void tlmRmtCfgSrvApp::InitVin(void) {
    
    //memcpy(mServiceVin, "SERVICEVIN1234567", TLM_SERVICE_VIN_LEN);

    //set default vin code
    memcpy(mGenericVin, "0000000000", TLM_GENERIC_VIN_LEN);

}

/**
* \brief OnInitialization: when process is ready, this function shall be called.
*                     It calls API to initialize admin, web, navi parameters.
*                     It also calls API to get language, generic vin and version information.
*                     After that it start a 3s timer to check if there is unfinished get/set session.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_001]
*/
void tlmRmtCfgSrvApp::OnInitialization(void) {

    
    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);
    
    InitParaAdmin();

    InitParaWeb(); 

    InitParaNavi(); 

    InitVin(); 

    entISysConfiguration_GetLanguage();

    entISysVf_GetNewVINDetected();

    entISysEngMode_GetIMX_version();

    //start a timer, after this then check uncomplete message
    gTeleTimer.SetTimer(RmtCfgInitDelayTimer, TLM_RMT_CFG_INIT_DELAY_TIMEOUT, EVT_RMTCFG_InitDelay, NIL);
    
}


/**
* \brief OnCheckUncompleteMsg: After initialization, there is a 3s delay to get initialized information, then it call this 
*                       function to check if there is unfinished set/get session. If yes, trigger new get/set session.
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
*/
void tlmRmtCfgSrvApp::OnCheckUncompleteMsg(void){

    DWORD status = ER_ERG_SUCCESS;
    uint32_t u32RegSize = 0;

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

    memset(GetMsgBuf, 0, sizeof(GetMsgBuf));
    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_GET,
                                                    static_cast<uint8_t*> (GetMsgBuf), sizeof(GetMsgBuf), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>, retry Get session\n", __FUNCTION__);
        
        mGetSessionRetryCnt = TLM_RMT_CFG_MAX_RETRY_CNT;
        gTeleQueue.postEvent(EVT_RMTCFG_GetCfgRetry, NIL);
        
    }

    memset(SetMsgBuf, 0, sizeof(SetMsgBuf));

    status = ssw_ergUserReadData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_SET,
                                                    static_cast<uint8_t*> (SetMsgBuf), sizeof(SetMsgBuf), &u32RegSize);

    if(status == ER_ERG_SUCCESS)
    {
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>, retry Set session\n", __FUNCTION__);
        
        mSetSessionRetryCnt = TLM_RMT_CFG_MAX_RETRY_CNT;
        gTeleQueue.postEvent(EVT_RMTCFG_SetCfgRetry, NIL);        
    }
}


/**
* \brief OnSetCfgRetry: After reboot, if there is unfinished set session, it shall retry to finish it. it retries
*                  every 10min, and totally 3 times, when the 10mins time out, this function shall be called.
*                  It reduces the mSetSessionRetryCnt
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_024]
*/
void tlmRmtCfgSrvApp::OnSetCfgRetry(void){
    tlmServiceMsg* srvMsg = NIL;
    
    //create a new srvMsg instance, it shall pass to the service, and delete by the service
    srvMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(SetMsgBuf, SIZE_ERG_DPCA_TLM_REMOTECFG_SET);
    
    if(mSetSessionRetryCnt>0)
    {
        gTeleTimer.SetTimer(RmtCfgSetCfgRetryTimer, TLM_RMT_CFG_RETRY_TIMEOUT, EVT_RMTCFG_SetCfgRetry, NIL);
    
        __OnReceiveMsg(srvMsg);

        mSetSessionRetryCnt--;        
    }
    
}

/**
* \brief OnGetCfgRetry: After reboot, if there is unfinished get session, it shall retry to finish it. it retries
*                  every 10min, and totally 3 times, when the 10mins time out, this function shall be called.
*                  It reduces the mGetSessionRetryCnt
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_025]
*/
void tlmRmtCfgSrvApp::OnGetCfgRetry(void){
    tlmServiceMsg* srvMsg = NIL;


    //create a new srvMsg instance, it shall pass to the service, and delete by the service
    srvMsg = tlmServiceFactory::GetInstance()->CreateSrvMsg(GetMsgBuf, SIZE_ERG_DPCA_TLM_REMOTECFG_GET);
    
    if(mGetSessionRetryCnt>0)
    {
        gTeleTimer.SetTimer(RmtCfgGetCfgRetryTimer, TLM_RMT_CFG_RETRY_TIMEOUT, EVT_RMTCFG_GetCfgRetry, NIL);
        __OnReceiveMsg(srvMsg);

        mGetSessionRetryCnt--;        
    }
    
}

/**
* \brief OnCompleteGetCfg: When the get configuration session finished successfully, this function shall be called
*                   It shall delete currenting Get Cfg message in persistency, and if there is no Set session, it shall request
*                   to shutdown the connection
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_020]
*/
void tlmRmtCfgSrvApp::OnCompleteGetCfg(){
    //reset the retry cnt
    mGetSessionRetryCnt = 0; 

    //clean the connection for get config 
    mConnSessionFlag &= ~(TLM_RMT_CFG_GET_SESSION_MASK);

    if(!mConnSessionFlag)
    {//no connection needed.
        ConnMgrApp* pConnMgrApp = const_cast<ConnMgrApp*>(&(ConnMgrApp::getInstance()));
        if(pConnMgrApp)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> close connection session\n", __FUNCTION__);
        
            pConnMgrApp->onReqDisconnection(tlmSrcTlm,mConnSessionId);
        }
        else
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> connMgrApp is NIL\n", __FUNCTION__);
        }
       
    }
    

    if(mCurGetCfgMsg != NIL)
    {
        delete mCurGetCfgMsg;
        mCurGetCfgMsg = NIL;
    }

    ssw_ergUserDeleteData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_GET);
}

/**
* \brief OnCompleteSetCfg: When the set configuration session finished successfully, this function shall be called
*                   It shall delete currenting pending message in persistency, and if there is no Get session, it shall request
*                   to shutdown the connection
*
* \note
*
* \param[in]
* - none
*
* \return 
* - none
*
* [Covers: MRN_TLM-RMTCFG_SW_DD_021]
*/
void tlmRmtCfgSrvApp::OnCompleteSetCfg(){    

    //clean retry cnt so it shall not retry.
    mSetSessionRetryCnt = 0;

    //clean the connection for set config 
    mConnSessionFlag &= ~(TLM_RMT_CFG_SET_SESSION_MASK);

    if(!mConnSessionFlag)
    {//no connection needed.
        ConnMgrApp* pConnMgrApp = const_cast<ConnMgrApp*>(&(ConnMgrApp::getInstance()));
        if(pConnMgrApp)
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> close connection session\n", __FUNCTION__);
        
            pConnMgrApp->onReqDisconnection(tlmSrcTlm,mConnSessionId);
        }
        else
        {
            LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> connMgrApp is NIL\n", __FUNCTION__);
        }
       
    }
    
    
    if(mCurPendingMsg != NIL)
    {
        delete mCurPendingMsg;
        mCurPendingMsg = NIL;
    }

    ssw_ergUserDeleteData(ERG_USER_SYSTEM, ERG_DPCA_TLM_REMOTECFG_SET);
}

/**
* \brief GetGetCfgMsgId: Interface to get message  ID of get session
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint16_t
*
*/
uint16_t tlmRmtCfgSrvApp::GetGetCfgMsgId(void) const{
    uint16_t msgId=0;
    if(mCurGetCfgMsg!=NIL)
    {
        msgId = mCurGetCfgMsg->GetMsgUniqueId();
    }

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>uniqueID:%x\n", __FUNCTION__, msgId);

    return msgId;
}
/**
* \brief GetSetCfgMsgId: Interface to get message ID of set session
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint16_t
*
*/
uint16_t tlmRmtCfgSrvApp::GetSetCfgMsgId(void) const{
    uint16_t msgId=0;
    if(mCurPendingMsg!=NIL)
    {
        msgId = mCurPendingMsg->GetMsgUniqueId();
    }

    LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>uniqueID:%x\n", __FUNCTION__, msgId);

    return msgId;
}

/**
* \brief GetGenericVin: Interface to get generic vin
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint8_t *
*
*/
uint8_t* tlmRmtCfgSrvApp::GetGenericVin(void) const{
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);
        return const_cast<uint8_t*>(mGenericVin);
}

/**
* \brief GetServiceVin: Interface to get service vin
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint8_t *
*
*/
uint8_t* tlmRmtCfgSrvApp::GetServiceVin(void) const{
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

        return  mParaAdmin.GetVinCode();
}

/**
* \brief GetLanguage: Interface to get language
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint8_t
*
*/
uint8_t tlmRmtCfgSrvApp::GetLanguage(void) const{
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

        return  mLanguage;
}

/**
* \brief GetSwVersion: Interface to get SW version
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint8_t *
*
*/
uint8_t* tlmRmtCfgSrvApp::GetSwVersion(void) const{
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s>\n", __FUNCTION__);

        return  const_cast<uint8_t*>(mSysInfoImx.Main_Application_version);
}

/**
* \brief CheckConnState: Check the connection status, if it's CS_CONNECTED, it shall post out event EVT_RMTCFG_ConnAvailable
*
* \note
*
* \param[in]
* - none
*
* \return 
* - uint8_t *
*
*/
void tlmRmtCfgSrvApp::CheckConnState(uint32_t status) const{  /*DG CPP2ISQP-ISQPcpp Rule 8.7.1-SCC_GRANT_0006*/
        LOG_PRINT(DPCA_TELE_MAIN_INFO,"[TLM_MSGSRV]:<%s> status[%d]\n", __FUNCTION__, status);

        if(status == CS_CONNECTED)
        {
            gTeleQueue.postEvent(EVT_RMTCFG_ConnAvailable, NIL);
        }

        return  ;
}


